﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using LeadThing.AbpZeroTemplate.CaseCategorys.Authorization;
using LeadThing.AbpZeroTemplate.CaseCategorys.Dtos;
using LeadThing.AbpZeroTemplate.Dto;



namespace LeadThing.AbpZeroTemplate.CaseCategorys
{
    /// <summary>
    /// 矛盾纠纷案例菜单表服务实现
    /// </summary>
    [AbpAuthorize(CaseCategoryAppPermissions.CaseCategory)]


    public class CaseCategoryAppService : AbpZeroTemplateAppServiceBase, ICaseCategoryAppService
    {
        private readonly IRepository<CaseCategory, long> _caseCategoryRepository;
        private readonly ICaseCategoryListExcelExporter _caseCategoryListExcelExporter;


        private readonly CaseCategoryManage _caseCategoryManage;
        /// <summary>
        /// 构造方法
        /// </summary>
        public CaseCategoryAppService(IRepository<CaseCategory, long> caseCategoryRepository,
CaseCategoryManage caseCategoryManage
      , ICaseCategoryListExcelExporter caseCategoryListExcelExporter
  )
        {
            _caseCategoryRepository = caseCategoryRepository;
            _caseCategoryManage = caseCategoryManage;
            _caseCategoryListExcelExporter = caseCategoryListExcelExporter;
        }


        #region 实体的自定义扩展方法
        private IQueryable<CaseCategory> _caseCategoryRepositoryAsNoTrack => _caseCategoryRepository.GetAll().AsNoTracking();


        /// <summary>
        /// 获取全部纠纷案例数据加载页面数据
        /// </summary>
        /// <returns></returns>
        public List<CaseCategoryListDto> GetAllCaseCategorysLoadPage(GetCaseCategoryInput input)
        {
            var query = _caseCategoryRepository.GetAll();

            if (input.ParentID > -1)
            {
                query = query.Where(p => p.ParentID == input.ParentID);
            }

            if (input.Layer > 0)
            {
                query = query.Where(p => p.Layer == input.Layer);
            }

            return query.OrderBy(p => p.Id).ToList().MapTo<List<CaseCategoryListDto>>();
        }

        ///// <summary>
        ///// 递归排序
        ///// </summary>
        ///// <param name="caseCategory"></param>
        ///// <param name="allCaseCategorys"></param>
        ///// <param name="result"></param>
        ///// <param name="level"></param>
        //private void AddCaseCategoryLoadPage(CaseCategory caseCategory, List<CaseCategory> allCaseCategorys, List<CaseCategoryListDto> result, int level)
        //{
        //    var flatCaseCategory = caseCategory.MapTo<CaseCategoryListDto>();
        //    flatCaseCategory.Layer = level;
        //    flatCaseCategory.DisplayTitle = flatCaseCategory.Title;
        //    result.Add(flatCaseCategory);

        //    var child = allCaseCategorys.Where(i => i.ParentID == caseCategory.Id);
        //    if (child.Count() == 0)
        //    {
        //        return;
        //    }

        //    var children = allCaseCategorys.Where(p => p.ParentID != 0 && p.ParentID == caseCategory.Id).ToList();

        //    foreach (var childCaseCategory in children)
        //    {
        //        AddCaseCategoryLoadPage(childCaseCategory, allCaseCategorys, result, level + 1);
        //    }
        //}

        /// <summary>
        /// 获取全部案例
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<CaseCategoryListDto>> GetCaseCategorys()
        {
            var query =
                from ou in _caseCategoryRepository.GetAll()
                select new { ou };

            var items = await query.ToListAsync();

            return new ListResultDto<CaseCategoryListDto>(
                items.Select(item =>
                {
                    var dto = item.ou.MapTo<CaseCategoryListDto>();
                    return dto;
                }).ToList());
        }

        /// <summary>
        /// 获取全部地区树形数据
        /// </summary>
        /// <returns></returns>
        public List<ComboboxItemDto> GetCaseCategoryTree()
        {
            var list = GetAllCaseCategorys().Select(p => new ComboboxItemDto(
                 p.Id.ToString(),
                 p.DisplayTitle
                  )).ToList();
            list.Insert(0, new ComboboxItemDto("0", "无父级分类"));
            return list;
        }

        /// <summary>
        /// 树形排序
        /// </summary>
        /// <returns></returns>
        private List<CaseCategoryListDto> GetAllCaseCategorys()
        {
            var caseCategorys = _caseCategoryRepository.GetAll().OrderBy(p => p.Id).ToList();
            var rootCaseCategorys = caseCategorys.Where(p => p.ParentID == 0).OrderBy(p => p.Id);

            var result = new List<CaseCategoryListDto>();

            foreach (var rootCaseCategory in rootCaseCategorys)
            {
                var level = 0;
                AddCaseCategory(rootCaseCategory, caseCategorys, result, level);
            }

            return result;
        }

        /// <summary>
        /// 递归排序
        /// </summary>
        /// <param name="caseCategory"></param>
        /// <param name="allCaseCategorys"></param>
        /// <param name="result"></param>
        /// <param name="level"></param>
        private void AddCaseCategory(CaseCategory caseCategory, List<CaseCategory> allCaseCategorys, List<CaseCategoryListDto> result, int level)
        {
            var flatCaseCategory = caseCategory.MapTo<CaseCategoryListDto>();
            flatCaseCategory.Layer = level;
            string layers = new string('—', caseCategory.Layer);
            flatCaseCategory.DisplayTitle = layers + flatCaseCategory.Title;
            result.Add(flatCaseCategory);

            var child = allCaseCategorys.Where(i => i.ParentID == caseCategory.Id);
            if (child.Count() == 0)
            {
                return;
            }

            var children = allCaseCategorys.Where(p => p.ParentID != 0 && p.ParentID == caseCategory.Id).ToList();

            foreach (var childCaseCategory in children)
            {
                AddCaseCategory(childCaseCategory, allCaseCategorys, result, level + 1);
            }
        }


        #endregion


        #region 矛盾纠纷案例菜单表管理

        /// <summary>
        /// 根据查询条件获取矛盾纠纷案例菜单表分页列表
        /// </summary>
        public async Task<PagedResultDto<CaseCategoryListDto>> GetPagedCaseCategorysAsync(GetCaseCategoryInput input)
        {

            var query = _caseCategoryRepositoryAsNoTrack;
            //TODO:根据传入的参数添加过滤条件

            var caseCategoryCount = await query.CountAsync();

            var caseCategorys = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var caseCategoryListDtos = caseCategorys.MapTo<List<CaseCategoryListDto>>();
            return new PagedResultDto<CaseCategoryListDto>(
            caseCategoryCount,
            caseCategoryListDtos
            );
        }

        /// <summary>
        /// 通过Id获取矛盾纠纷案例菜单表信息进行编辑或修改 
        /// </summary>
        public async Task<GetCaseCategoryForEditOutput> GetCaseCategoryForEditAsync(NullableIdDto<long> input)
        {
            var output = new GetCaseCategoryForEditOutput();

            CaseCategoryEditDto caseCategoryEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _caseCategoryRepository.GetAsync(input.Id.Value);
                caseCategoryEditDto = entity.MapTo<CaseCategoryEditDto>();
            }
            else
            {
                caseCategoryEditDto = new CaseCategoryEditDto();
            }

            output.CaseCategory = caseCategoryEditDto;
            return output;
        }


        /// <summary>
        /// 通过指定id获取矛盾纠纷案例菜单表ListDto信息
        /// </summary>
        public async Task<CaseCategoryListDto> GetCaseCategoryByIdAsync(EntityDto<long> input)
        {
            var entity = await _caseCategoryRepository.GetAsync(input.Id);

            return entity.MapTo<CaseCategoryListDto>();
        }







        /// <summary>
        /// 新增或更改矛盾纠纷案例菜单表
        /// </summary>
        public async Task CreateOrUpdateCaseCategoryAsync(CreateOrUpdateCaseCategoryInput input)
        {
            if (input.CaseCategoryEditDto.Id.HasValue)
            {
                await UpdateCaseCategoryAsync(input.CaseCategoryEditDto);
            }
            else
            {
                await CreateCaseCategoryAsync(input.CaseCategoryEditDto);
            }
        }

        /// <summary>
        /// 新增矛盾纠纷案例菜单表
        /// </summary>
        [AbpAuthorize(CaseCategoryAppPermissions.CaseCategory_CreateCaseCategory)]
        public virtual async Task<CaseCategoryEditDto> CreateCaseCategoryAsync(CaseCategoryEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = input.MapTo<CaseCategory>();

            entity.Id = await _caseCategoryRepository.InsertOrUpdateAndGetIdAsync(entity);
            entity = await _caseCategoryRepository.GetAsync(entity.Id);

            //查询父节点的深度赋值
            if (entity.ParentID > 0)
            {
                CaseCategory model = _caseCategoryRepository.FirstOrDefault(p => p.Id == entity.ParentID);
                entity.Layer = model.Layer + 1;
            }
            else
            {
                entity.ClassList = "," + entity.Id + ",";
                entity.Layer = 1;
            }

            //修改节点列表和深度
            entity = await _caseCategoryRepository.UpdateAsync(entity);
            return entity.MapTo<CaseCategoryEditDto>();
        }

        /// <summary>
        /// 编辑矛盾纠纷案例菜单表
        /// </summary>
        [AbpAuthorize(CaseCategoryAppPermissions.CaseCategory_EditCaseCategory)]
        public virtual async Task UpdateCaseCategoryAsync(CaseCategoryEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _caseCategoryRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _caseCategoryRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除矛盾纠纷案例菜单表
        /// </summary>
        [AbpAuthorize(CaseCategoryAppPermissions.CaseCategory_DeleteCaseCategory)]
        public async Task DeleteCaseCategoryAsync(EntityDto<long> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _caseCategoryRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除矛盾纠纷案例菜单表
        /// </summary>
        [AbpAuthorize(CaseCategoryAppPermissions.CaseCategory_DeleteCaseCategory)]
        public async Task BatchDeleteCaseCategoryAsync(List<long> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _caseCategoryRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        #endregion

        #region 矛盾纠纷案例菜单表的Excel导出功能


        public async Task<FileDto> GetCaseCategoryToExcel()
        {
            var entities = await _caseCategoryRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<CaseCategoryListDto>>();

            var fileDto = _caseCategoryListExcelExporter.ExportCaseCategoryToFile(dtos);



            return fileDto;
        }


        #endregion

    }
}
